#include "gtest/gtest.h"

#include "helper/Singleton.h"
//singleton 
// OK - 1. helper template class for easy writing singleton code
// OK 2. How to assert singleton???   > Addr(singleton()) == Addr(singleton())
// OK 4.create before main :  ASSERT_EQ(EXPECT.ctor(), TRACER); > ASSERT create timestamp of TRACER  before the Singleton


#include "helper/unittest/Tracer.h"
class TracerForFactory {
public:
    static helper::unittest::Tracer & tracer(){
        static helper::unittest::Tracer __tracer;
        object.ensureConstructed();
        return __tracer;
    }

private:
    struct CreaterBeforeMain {
        CreaterBeforeMain(){
            TracerForFactory::tracer();
        }
        void ensureConstructed() const {}
    };
    static struct CreaterBeforeMain object;
};
TracerForFactory::CreaterBeforeMain TracerForFactory::object;


class Factory : public helper::Singleton<Factory>{
public:
    Factory(){
        TracerForFactory::tracer().reset().ctor();
    }
    ~Factory() override{}

    Factory * getAddr(){ return this; }
};

TEST(SingletonTest, testAddrEqual){
    { // testCreateBeforeMain
        EXPECT.reset().ctor();
        // TRACER.reset();
        // before main -> call Factory 's constructor add ctor to TRACER
        ASSERT_EQ(EXPECT.toString(),  TracerForFactory::tracer().toString());
    }

    ASSERT_EQ(Factory::instance().getAddr(), Factory::instance().getAddr());
}

//TODO: thread-safe test for singleton
//  2-thread  -> ASSERT_EQ(get() == get());
